# -*- coding: utf-8 -*-
import importlib
import sys
import threading
import zipfile

import requests
import tqdm
from PyQt6 import QtWidgets
from PyQt6.QtWidgets import QMessageBox

from pyqt_6.ui_py.ui_Main import Ui_MainWindow
from pyqt_6.ui_py.ui_authcode_calc_Main import Ui_AuthcodeCalcMainWindow
from pyqt_6.ui_py.ui_character_convert_Main import Ui_CharacterConvertMainWindow
from utils.common.crc16 import crc16_modbus_little_endian
from utils.common.dumpUtil import filter_non_hex_chars

# 空字典用于存储socket
socket_dict = {}
# 初始化一个事件对象,用于通知定时器线程结束
timer_event = threading.Event()


def get_current_version_from_file(default_version="1.1"):
    try:
        with open('v.txt', 'r') as f:
            current_server_version = f.read().strip()  # 读取版本号并去除空白符
            return current_server_version
    except FileNotFoundError:
        print("Error: v.txt 文件未找到。")
        # 如果文件不存在，创建文件并写入默认版本号
        with open('v.txt', 'w') as f:
            f.write(default_version)
        return None  # 处理文件不存在的情况


# 获取版本号的html页面
def get_version_from_url(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        return response.text
    except requests.exceptions.RequestException as e:
        print(f"Error: 无法获取页面 - {e}")
        return None


# 从 HTML 中手动提取版本号
def extract_version_from_html(html):
    # 手动查找包含 class="line" 和 id="LC1" 的 div 标签
    start_tag = "<div class='line' id='LC1'>"
    end_tag = "</div>"

    # 查找起始和结束标签的位置
    start_index = html.find(start_tag)
    if start_index == -1:
        return None

    # 计算内容的起始位置
    start_index += len(start_tag)
    end_index = html.find(end_tag, start_index)

    if end_index == -1:
        return None

    # 提取出标签中的内容
    version = html[start_index:end_index].strip()

    # 替换 HTML 实体字符为对应的符号
    version = version.replace('&#x000A;', '')  # 替换 &#x000A; (换行符) 为空字符

    return version


def show_update_prompt():
    msg_box = QMessageBox()
    msg_box.setIcon(QMessageBox.Icon.Information)
    msg_box.setText("有新版本，是否进行升级？")
    msg_box.setWindowTitle("新版本升级提示")
    msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
    result = msg_box.exec()
    return result == QMessageBox.StandardButton.Yes


def perform_update(new_version):
    # 执行升级逻辑，例如下载新版本、进度条滚动、替换文件等
    new_version = new_version.strip()
    v_new_version = new_version
    download_url = f"https://gitee.com/vonjia/jt808/releases/download/{new_version}/JT808_{new_version}_Windows_x86_64.zip"
    response = requests.get(download_url, stream=True)

    # 显示下载进度
    total_size = int(response.headers.get('content-length', 0))
    new_version = f"JT808_{new_version}_Windows_x86_64.zip"
    with open(new_version, 'wb') as f, tqdm.tqdm(total=total_size, unit='iB', unit_scale=True, disable=True) as pbar:
        for chunk in response.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
                pbar.update(len(chunk))
    # 解压更新文件
    with zipfile.ZipFile(new_version, 'r') as zip_ref:
        zip_ref.extractall('.')
    with open('v.txt', 'w') as f:
        f.write(v_new_version)


def check_for_update(current_version_inner):
    # 模拟检测新版本的网络请求
    server_temp_version = get_version_from_url("https://gitee.com/vonjia/jt808/blob/master/v.txt")
    server_temp_version = extract_version_from_html(server_temp_version)
    if current_version_inner != server_temp_version:
        return True, server_temp_version
    else:
        return False, server_temp_version


# 校验码计算子窗口
class AuthcodeWindow(QtWidgets.QMainWindow, Ui_AuthcodeCalcMainWindow):  # 使用 QMainWindow 而不是 QWidget
    def __init__(self):
        super(AuthcodeWindow, self).__init__()
        self.ui = Ui_AuthcodeCalcMainWindow()  # 实例化 UI 类
        self.ui.setupUi(self)  # 设置 UI

    def print_authcode(self):
        # pass
        data = self.ui.dumpText.toPlainText().upper()
        data = filter_non_hex_chars(data)  # 调用规范报文方法
        authcode = crc16_modbus_little_endian(data)
        self.ui.dumpText_2.setPlainText("CRC16校验码:" + authcode)


# 字符转换计算子窗口
class CharacterConvertWindow(QtWidgets.QMainWindow, Ui_CharacterConvertMainWindow):  # 使用 QMainWindow 而不是 QWidget
    def __init__(self):
        super(CharacterConvertWindow, self).__init__()
        self.ui = Ui_CharacterConvertMainWindow()  # 实例化 UI 类
        self.ui.setupUi(self)  # 设置 UI

    def print_convert_result(self):
        # pass
        data = self.ui.dumpText.toPlainText().upper()
        data = filter_non_hex_chars(data)  # 调用规范报文方法
        authcode = crc16_modbus_little_endian(data)
        self.ui.dumpText_2.setPlainText(authcode)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    """
        初始化
    """

    def __init__(self):
        super(MainWindow, self).__init__()
        # super().__init__()  # 直接调用父类的构造函数
        self.new_window = None
        self.setupUi(self)
        self.sock = None  # 用于保存socket对象
        self.show()  # 显示窗口

    def on_combobox_changed(self):
        # module = None  # 或者设置为某个默认值
        # 清理先前导入的模块（如果有）
        if hasattr(self, 'module'):
            del self.module
        # 获取当前选择的文本
        selected_text = self.comboBox.currentText()
        # 根据选择的文本调用相应的处理逻辑
        if selected_text == "云快充-1.6":
            # 动态导入kc_16.py模块
            module = importlib.import_module("packet.kc_16.kc16_header")
        elif selected_text == "云快充-1.5":
            module = importlib.import_module("packet.kc_15.kc15_header")
        return module

    # 主解析结果输出方法
    def parse_print(self):
        module = self.on_combobox_changed()
        parser = module.KC16Parser()
        data = self.dumpText.toPlainText().upper()
        data = filter_non_hex_chars(data)  # 调用规范报文方法
        start_flag = '68'
        messages = []
        total_messages = 0
        start_index = 0
        result_strings = []  # 使用列表存储所有解析结果
        data = data.upper()
        while start_index < len(data):
            #  # 查找每个报文的起始标志 '68'
            start_index = data.find(start_flag, start_index)
            if start_index == -1:
                break  # 没有找到更多的起始标志
            # 获取第二个字节的值，表示报文长度
            length_byte = data[start_index + 2:start_index + 4]  # 第二个字节
            length = int(length_byte, 16)  # 将十六进制的字节值转换为十进制

            # 计算报文的总长度
            message_length = 4 + length * 2  # 报文从第三个字节开始，计算总长度

            # 提取该报文内容，包含起始标志到结束字节（倒数第三个字节前）
            message = data[start_index:start_index + message_length + 4]
            messages.append(message)
            # 移动起始索引，准备查找下一个报文
            start_index += message_length
            total_messages += 1
            result_strings.append(
                f'===============================第{total_messages}条包===============================\n' + parser.parse(
                    message))  # 追加解析结果
            # 跳过校验码后的报文内容，继续查找下一个start_flag
            start_index += message_length + 4  # 跳过当前报文及其校验码（报文+校验码占4位）
        # 将所有解析结果合并为一个字符串
        final_result = "\n".join(result_strings)
        self.dumpParseText.setPlainText(final_result)

    # 打开校验码计算子窗体
    def open_authcode_calc_window(self):
        self.new_window = AuthcodeWindow()
        self.new_window.show()

    # 打开字符转换子窗体
    def open_character_convert_window(self):
        self.new_window = CharacterConvertWindow()
        self.new_window.show()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    current_version = get_current_version_from_file()  # 你的当前版本号
    has_update, server_version = check_for_update(current_version)
    if has_update:
        if show_update_prompt():
            perform_update(server_version)
            app.quit()
            window = MainWindow()  # 覆盖原窗口
    sys.exit(app.exec())
